#include <stdio.h>
#include <assert.h>
#include <unistd.h>
#include <sys/wait.h>
#include "./include/ipc.h"

pid_t fork_consumer(char * const argv[]);  // 创建消费者进程

int main(int argc, char *argv[])
{
    //
    // 申请共享内存
    //
    int shmid = get_shm(SHM_KEY);
    //
    // 绑定共享内存到进程地址空间
    //
    shmd_t* shmd_ptr = (shmd_t*)attach_shm(shmid);

    //
    // 申请信号量
    //
    int metuxid = get_sem(MUTEX_KEY);
    int fullid = get_sem(FULL_KEY);
    int emptyid = get_sem(EMPTY_KEY);

    //
    // 创建消费者进程
    //
    pid_t pid = fork_consumer(argv);

    printf("producer start work: \n");

    //
    // 不断地生产数据
    //
    for(int i=1; ; i++) {

        if( 0 == shmd_ptr->p_speed ) {
            //
            // 接收到 manager 的停止生产命令
            //
            sem_pv(metuxid, -1);
                shmd_ptr->p = -1;       // 通知消费者自己已经停止生产
            sem_pv(metuxid, 1);
            break;
        }

        usleep(1000 * shmd_ptr->p_speed);  // 控制生产速率

        sem_pv(emptyid, -1);    // p操作
        sem_pv(metuxid, -1);    // p操作
            (shmd_ptr->num)++;
            shmd_ptr->buffer[shmd_ptr->p] = i;  
            shmd_ptr->p = (shmd_ptr->p + 1) % BUFFER_SIZE;
            printf("producer create data %d [spd: %d]\n", i, shmd_ptr->p_speed);
        sem_pv(metuxid, 1);     // v操作
        sem_pv(fullid, 1);      // v操作
    }

    //
    // 等待消费者进程结束
    //
    printf("produce over!\n");
    printf("totally produce %d data\n", shmd_ptr->num);
    printf("waiting for consumer!\n");

    int state;
    wait(&state);

    printf("consumer exit with %d\n",state);

    //
    // 通知 manager 消费者也已经消费完
    //
    sem_pv(metuxid, -1);
        shmd_ptr->c = -1;
    sem_pv(metuxid, 1);

    return 0;
}

/*
 * 创建消费者进程
 */
pid_t fork_consumer(char *const * argv)
{
    pid_t pid = fork();
    assert(0 <= pid);
    if(0 == pid) {
        //
        // 子进程 
        //
        printf("fork consumer success!\n");
        assert( -1 != execv("./consumerMain", argv) );
    }
    sleep(1);
    return pid;
}

